from qa_engine.nlp import ZhcnSeg, SentenceSimilarity
from qa_engine.handler.base import BaseHandler
from qa_engine.user import User
from qa_engine.util import read_config_path
import codecs


class SimilarityHandler(BaseHandler):
    """
    根据问句相似度进行回答
    """

    def handle(self, question: str, user: User = None, _position: str = ''):
        """
        根据输入回应, handler接口
        :param question: 问题
        :param user: 用户
        :param _position: 位置
        :return: 如果能够回应, 则返回回应 格式 str[], 否则 None
        """
        # 通过检索相似问题的方式回复
        # 与预先准备好的问答中的问句进行比较,
        # 如果相似度最高的大于self.min_score则以该问句的固定回答来回答
        most_sim_questions = self.sent_sim.similarity_top_k(question, 3)
        print('most_sim_questions:', most_sim_questions)
        answer_list = []
        for item in most_sim_questions:
            answer = self.qa_pair_dict[item[0]]
            answer_list.append(
                {"question": item[0], "answer": answer, "score": str(item[1])}
            )
        response = dict(answer_list[0])
        if float(response['score']) > self.min_score:
            user.intent.set_intent(response['answer'])
            return [response['answer']]
        return None

    def __init__(self, config: dict):
        """
        :param config: 配置
        """
        super().__init__(config)
        # 如果相似度得分超过该值就返回相应的回答
        self.min_score = self.config['min-score']
        self._load_qa_data_util()

    def _load_qa_data_util(self):
        """
        加载问答初始化数据列表和工具
        :return:
        """
        # 初始化，加载问答列表
        self.qa_pair_dict = {}
        # TODO: 此类数据应该引入数据库中
        q_list = []
        with open(read_config_path(self.config['question-answer']),
                  'r', encoding='utf8') as in_file:
            for line in in_file.readlines():
                q_str = line.split('\t')[0]
                a_str = line.split('\t')[-1].strip()
                q_list.append(q_str)
                self.qa_pair_dict[q_str] = a_str

        # 读取停用词
        file_obj = codecs.open(
            read_config_path(self.config['stop-word']),
            'r', 'utf-8')
        stopwords = []
        while True:
            line = file_obj.readline()
            line = line.strip('\r\n')
            if not line:
                break
            stopwords.append(line)
        file_obj.close()

        # 相似度计算工具
        self.sent_sim = SentenceSimilarity(ZhcnSeg(stopwords))
        self.sent_sim.set_sentences(q_list)
        # 默认用tfidf
        self.sent_sim.tfidf_model()
        # cls.sent_sim.LsiModel()
        # cls.sent_sim.LdaModel()
